package com.cn.springcloudwechat.upload;

import com.alibaba.fastjson.JSON;
import com.cn.springcloudwechat.model.cos.CosClientEntity;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.exception.CosClientException;
import com.qcloud.cos.exception.CosServiceException;
import com.qcloud.cos.model.*;
import java.io.*;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class CosSplit {
    static String uploadId = "";

    // 方法 1 初始化分块上传
    public static InitiateMultipartUploadResult initiateMultipartUpload1(File file
    ) throws CosClientException, CosServiceException, FileNotFoundException {
        //初始化cos
        COSClient cosClient = CosClientEntity.getInstace();

        // 初始化分块
        InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest(CosClientEntity.bucketName, CosClientEntity.movieKey);
        InitiateMultipartUploadResult initResponse = cosClient.initiateMultipartUpload(initRequest);

        System.out.println("初始化分块:" + JSON.toJSONString(initResponse));
        //上传分块
        UploadPartRequest uploadPartRequest = new UploadPartRequest();
        uploadPartRequest.setBucketName(CosClientEntity.bucketName);
        uploadPartRequest.setKey(CosClientEntity.movieKey);
        uploadPartRequest.setUploadId(initResponse.getUploadId());
        uploadPartRequest.setPartNumber(1);
        uploadPartRequest.setPartSize(4 * 1024 * 1024);
        uploadPartRequest.setFile(file);
        uploadPart(uploadPartRequest);
        return initResponse;
    }

    // 方法 2 上传数据分块
    public static List<PartETag> uploadPart(UploadPartRequest uploadPartRequest)
            throws CosClientException, CosServiceException, FileNotFoundException {
        COSClient cosClient = CosClientEntity.getInstace();
        List<PartETag> partETags = new ArrayList<PartETag>();
        // partStream 代表 part 数据的输入流, 流长度为 partSize
        UploadPartRequest uploadRequest = new UploadPartRequest().withBucketName(uploadPartRequest.getBucketName()).
                withUploadId(uploadPartRequest.getUploadId()).withKey(uploadPartRequest.getKey()).withPartNumber(uploadPartRequest.getPartNumber()).
                withFile(uploadPartRequest.getFile()).withPartSize(uploadPartRequest.getPartSize());
        UploadPartResult uploadPartResult = cosClient.uploadPart(uploadRequest);
        System.out.println("uploadPartResult:" + JSON.toJSONString(uploadPartResult));
        String eTag = uploadPartResult.getETag();  // 获取 part 的 Etag
        partETags.add(new PartETag(uploadPartRequest.getPartNumber(), eTag));  // partETags 记录所有已上传的 part 的 Etag 信息
        System.out.println("partETags:" + JSON.toJSONString(partETags));
        return partETags;
    }

    // 方法 3 完成分块上传
    public static CompleteMultipartUploadResult completeMultipartUpload(
            CompleteMultipartUploadRequest request) throws CosClientException, CosServiceException {
        COSClient cosClient = CosClientEntity.getInstace();
        // complete 完成分块上传.
        CompleteMultipartUploadRequest compRequest = new CompleteMultipartUploadRequest(request.getBucketName(), request.getKey(),
                request.getUploadId(), request.getPartETags());
        CompleteMultipartUploadResult result = cosClient.completeMultipartUpload(compRequest);
        return result;
    }

    // 方法 4 罗列已上传分块
    public static PartListing listParts(ListPartsRequest listPartsRequest)
            throws CosClientException, CosServiceException {
        COSClient cosclient = CosClientEntity.getInstace();
        // ListPart 用于在 complete 分块上传前或者 abort 分块上传前获取 uploadId 对应的已上传的分块信息, 可以用来构造 partEtags
        PartListing partListing = null;
        List<PartETag> partETags = new LinkedList<>();
        do {
            partListing = cosclient.listParts(listPartsRequest);
            for (PartSummary partSummary : partListing.getParts()) {
                partETags.add(new PartETag(partSummary.getPartNumber(), partSummary.getETag()));
            }
            listPartsRequest.setPartNumberMarker(partListing.getNextPartNumberMarker());
        } while (partListing.isTruncated());
        return partListing;
    }

    // 方法 5 终止分块上传
    public static void abortMultipartUpload(AbortMultipartUploadRequest request)
            throws CosClientException, CosServiceException {
        COSClient cosclient = CosClientEntity.getInstace();
        // abortMultipartUpload 用于终止一个还未 complete 的分块上传
        AbortMultipartUploadRequest abortMultipartUploadRequest =
                new AbortMultipartUploadRequest(request.getBucketName(), request.getKey(), request.getUploadId());
        cosclient.abortMultipartUpload(abortMultipartUploadRequest);

    }

}
